using System;
using System.Collections.Generic;
using System.Testing;
using Minions.Classes;
using MinionsEdit.Classes;
using Nsb.Classes;
using jQueryApi;

namespace MinionsEdit.Tests
{
    public static class MinionEditVerifier
    {
        public static void Verify(string id)
        {
            // ReSharper disable PossibleNullReferenceException
            MinionEdit mm = (MinionEdit) Minion.GetMinionById(id);
            jQueryObject el = jQuery.Select("#" + id);
            Assert.IsTrue(mm != null, String.Format("{0} is in the AllMinions list", id));
            Assert.IsTrue(mm is MiCanvasEdit, String.Format("{0} Type is {1}", id, typeof(MiCanvasEdit).FullName));
            Assert.IsTrue(el.Length > 0, String.Format("{0} is in the dom", id));
            Assert.IsTrue(mm.Element.Is(":visible"), String.Format("{0} is visible", id));
            Assert.IsTrue(el.GetDataValue(Minion.MinionClassName) == mm, String.Format("{0} is in the element data", id));
            Assert.IsTrue(mm.HostElement != null, String.Format("{0} has a host element", id));
            Assert.IsTrue(mm.TheCanvas != null, String.Format("{0} has canvas data", id));
            Assert.IsTrue(mm.TopMinion != null, String.Format("{0} has a top minion", id));
            Assert.IsTrue(mm.Editing, String.Format("{0} is flagged as Editing", id));
            Assert.IsTrue(mm.Data != null, String.Format("{0} has Data", id));
            Assert.IsTrue(mm.LiveData.id == id, String.Format("{0} Data has the correct id", id));
            Assert.IsTrue(mm.Children != null, String.Format("{0} Children is a dictionary", id));
            Assert.IsTrue(mm.Children.Count > 0 ? mm.Data.minions.Count > 0 : mm.Data.minions.Count == 0, String.Format("{0} is in the dom", id));

            if (mm.Children.Count > 0)
                foreach (KeyValuePair<string,Minion> pair in mm.Children)
                {
                    MinionEdit mm2 = (MinionEdit)pair.Value;
                    Verify(mm2.Id);
                    Assert.IsTrue(mm2.Parent != null && mm2.Parent == mm, String.Format("{0} Parent is correct", mm2.Id));
                }
            // ReSharper restore PossibleNullReferenceException
        }

        /// <summary>
        /// Re-id's testdata id's using supplied id's or the Formulas.NewId method
        /// </summary>
        /// <param name="md">test data</param>
        /// <param name="ids">full or partial list of ids to use. first is the parent. rest are the children</param>
        /// <returns></returns>
        public static MinionData NewTestData(MinionData md, string[] ids)
        {
            int sz = ids.Length;
            int cnt = 1;
            IReadonlyCollection<string> keys = md.minions.Keys;
            md.id = sz > 0 ? ids[0] : Formulas.NewId;
            foreach (KeyValuePair<string, MinionData> pair in md.minions)
            {
                if (cnt < sz && !new RegularExpression(@"^[a-z0-9_]*$", "gi").Test(ids[cnt]))
                    throw new Exception(String.Format("ID = [{0}]. Ids can contain letters, numbers, and underscore only.", ids[cnt]));
                string chid = pair.Key;
                string nwid = cnt >= sz ? Formulas.NewId : ids[cnt];
                md.minions[nwid] = md.minions[chid];
                md.minions[nwid].id = nwid;
                cnt++;
            }
            foreach (string s in keys)
                Type.DeleteField(md.minions, s);

            return md;
        }
    }
}